﻿namespace EasyWeb
{
    using System;
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
    using EasyWeb.Data;
    using EasyWeb.Extensions;
    using EasyWeb.Validation;

    public class EWEntityDefinition
    {
        private readonly EWStateBag stateBag = new EWStateBag();

        public Guid Id
        {
            get { return this.StateBag.Get<Guid>("Id"); }
            set { this.StateBag.Set("Id", value); }
        }

        [Display(ResourceType = typeof(EWEntityDefinitionResources), Name = "EntityDefinition_InternalName")]
        [Required]
        [StringLength(60)]
        [EWNameValidation]
        [DataType("EWInternalName")]
        public string InternalName
        {
            get { return this.StateBag.Get<string>("InternalName"); }
            set
            {
                EWGuard.IsNotNullOrEmpty(value, "value");
                this.StateBag.Set("InternalName", value);
            }
        }

        [Display(ResourceType = typeof(EWEntityDefinitionResources), Name = "EntityDefinition_DisplayName")]
        public EWText DisplayName
        {
            get { return this.StateBag.Get<EWText>("DisplayName", () => new EWText()); }
            set
            {
                EWGuard.IsNotNull(value, "value");
                this.StateBag.Set("DisplayName", value);
            }
        }

        [Display(ResourceType = typeof(EWEntityDefinitionResources), Name = "EntityDefinition_Description")]
        public EWText Description
        {
            get { return this.StateBag.Get<EWText>("Description", () => new EWText()); }
            set
            {
                EWGuard.IsNotNull(value, "value");
                this.StateBag.Set("Description", value);
            }
        }

        [Display(ResourceType = typeof(EWEntityDefinitionResources), Name = "EntityDefinition_CreatedBy")]
        public string CreatedBy
        {
            get { return this.StateBag.Get<string>("CreatedBy"); }
            set
            {
                EWGuard.IsNotNullOrEmpty(value, "value");
                this.StateBag.Set("CreatedBy", value);
            }
        }

        [Display(ResourceType = typeof(EWEntityDefinitionResources), Name = "EntityDefinition_Created")]
        public DateTime Created
        {
            get { return this.StateBag.Get<DateTime>("Created"); }
            set { this.StateBag.Set("Created", value); }
        }

        [Display(ResourceType = typeof(EWEntityDefinitionResources), Name = "EntityDefinition_ModifiedBy")]
        public string ModifiedBy
        {
            get { return this.StateBag.Get<string>("ModifiedBy"); }
            set
            {
                EWGuard.IsNotNullOrEmpty(value, "value");
                this.StateBag.Set("ModifiedBy", value);
            }
        }

        [Display(ResourceType = typeof(EWEntityDefinitionResources), Name = "EntityDefinition_Modified")]
        public DateTime Modified
        {
            get { return this.StateBag.Get<DateTime>("Modified"); }
            set { this.StateBag.Set("Modified", value); }
        }

        public byte[] Timestamp
        {
            get { return this.StateBag.Get<byte[]>("Timestamp"); }
            set
            {
                EWGuard.IsNotNull(value, "value");
                this.StateBag.Set("Timestamp", value);
            }
        }

        [Display(ResourceType = typeof(EWEntityDefinitionResources), Name = "EntityDefinition_FieldDefinitions")]
        public EWFieldDefinitionCollection FieldDefinitions
        {
            get
            {
                return this.StateBag.Get("FieldDefinitions", () =>
                {
                    var result = new EWFieldDefinitionCollection(this);

                    if (!this.IsTransient())
                    {
                        using (var ts = EWHelpers.Data.BeginTransaction())
                        {
                            var items = EWHelpers.Async.RunSync(async () => await EWExtensionManager.CompositionContainer.GetExportedValue<IEWFieldDefinitionDao>().SelectAsync());
                            ts.Complete();

                            if (!items.IsNullOrEmpty())
                            {
                                items = items.Where(i => i.EntityDefinitionId == this.Id);
                                result.AddRange(items);
                            }
                        }
                    }

                    return result;
                });
            }
        }

        public EWStateBag StateBag
        {
            get { return this.stateBag; }
        }
    }
}
